/*
 * Copyright 2009-2010 Nanjing RedOrange ltd (http://www.red-orange.cn)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package redora.client.mvp;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.ui.Label;
import redora.client.Fields;
import redora.client.Persistable;
import redora.client.constants.RedoraConstants;
import redora.client.ui.*;
import redora.client.util.Field;
import redora.client.util.GWTViewUtil;
import redora.client.validation.BusinessRuleViolation;

import java.util.logging.Logger;

import static java.util.logging.Level.INFO;
import static redora.client.util.Field.Type.Set;
import static redora.client.util.GWTViewUtil.getViolatedMessagelabelById;

/**
 * Base implementation of the edit view. Not all of the edit view can be set into
 * a library, therefor Redora will generate a PojoEditView for each pojo in your
 * project. These classes will extend this base class.<br>
 * The for will have all the pojo's attributes except the set attributes.
 * @author Nanjing RedOrange (www.red-orange.cn)
 */
public abstract class EditViewBase extends FieldedComposite implements EditView {
    static Logger l = Logger.getLogger("EditViewBase");

    protected static RedoraResource redoraResource = GWT.create(RedoraResource.class);
    protected static RedoraConstants redoraConstants = GWT.create(RedoraConstants.class);

    protected final Class<? extends Persistable> cls;
    protected final ClientFactory clientFactory;
    protected final FlowPanel panel;
    protected final Anchor cancelButton;
    protected final Anchor saveButton;
    protected final Image startImage;

    protected EditViewBase(Class<? extends Persistable> cls, ClientFactory clientFactory) {
        this.cls = cls;
        this.clientFactory = clientFactory;
        panel = new FlowPanel();
        startImage = new Image("images/loading.gif");
        panel.add(startImage);

        saveButton = new Anchor(redoraConstants.save());
        cancelButton = new Anchor(redoraConstants.cancel());

        //Add form fields: all fields except the set fields:
        Fields f = clientFactory.getLocator().locateFields(cls);
        int j = 0;
        for (int i = 0; i < f.fields().length; i++) {
            if (f.fields()[i].type != Set) {
                fields.add(f.fields()[i]);
            }
        }
        title = new Label();
        panel.add(title);
        this.initWidget(panel);

        l.log(INFO, "Init ready with " + fields.size() + " fields");
    }

    @Override
    public void violatedForm(BusinessRuleViolation[] businessRuleViolations) {
        for (BusinessRuleViolation violation : businessRuleViolations) {
            if (violation.field != null) {
                Widget widget = GWTViewUtil.getWidgetById(violation.field, panel);
                if (widget != null)
                    widget.getElement().addClassName(redoraResource.css().redoraBRViolated());
                redora.client.ui.Label messageLabel = getViolatedMessagelabelById(violation.field, panel);
                messageLabel.setText(clientFactory.getLocator().locateMessage().rule(cls.getName(), violation.ruleId, null));
                messageLabel.setVisible(true);
            }
        }
    }


    @Override
    public Panel panel() {
        return panel;
    }

    @Override
    public HasClickHandlers saveButton() {
        return saveButton;
    }

    @Override
    public HasClickHandlers cancelButton() {
        return cancelButton;
    }

    @Override
    public Image startImage() {
        return startImage;
    }

    final Label title;

    @Override
    public HasText title() {
        return title;
    }
}
